﻿module Sustainalytics.Navigation {

    import Routing = Sustainalytics.Routing;

    export class SiteMapNodeRouteResolverService implements ISiteMapNodeRouteResolverService {

        constructor(
            private $q: ng.IQService,
            private ClaimsAuthorizationService: Claims.IClaimsAuthorizationService,
            private RoutingService: Routing.IRoutingService) {
        }

        public resolveNodeRoute(node: SiteMapNode): ng.IPromise<SiteMapNodeRoute> {
            var ctx = this;

            var def = ctx.$q.defer<SiteMapNodeRoute>();

            if (node.path) {
                // get route info
                var routeInfo = ctx.RoutingService.routeInfoMap.getRouteInfo(node.path);

                if (!routeInfo) {
                    console.log('Sustainalytics.Navigation :: Could not resolve route for node with Code: ' + node.code + ' Path: ' + node.path + ' Title: ' + node.title);
                }

                // format path
                var formattedPath = ctx.formatPath(node);

                if (routeInfo) {
                    // check route security
                    var promiseIsAllowed = ctx.checkRouteSecurity(node, routeInfo.security);

                    promiseIsAllowed.then(isAllowed => {
                        var isVisible = true;
                        // create node route
                        if (node.code === "TOOLS") {
                            if (this.ClaimsAuthorizationService.Validate("api/v1/screeningtool", "GET", []) ||
                                this.ClaimsAuthorizationService.Validate("api/v1/datareportingtool", "GET", [])) {
                                if (this.ClaimsAuthorizationService.Validate("api/v1/screeningtool", "GET", [])) {
                                    formattedPath = "/tools/screening";
                                } else
                                    if (this.ClaimsAuthorizationService.Validate("api/v1/datareportingtool", "GET", [])) {
                                        formattedPath = "/tools/report";
                                    }
                                isAllowed = true;
                            } else {
                                isAllowed = false;
                            }
                        }
                        else if (node.code === "TOOLS_SCREENING") {
                            isAllowed = this.ClaimsAuthorizationService.Validate("api/v1/screeningtool", "GET", []);
                        }
                        else if (node.code === "TOOLS_REPORT") {
                            isAllowed = this.ClaimsAuthorizationService.Validate("api/v1/datareportingtool", "GET", []);
                        }
                        else if (node.code === "RESEARCH_RISKRATING" || node.code === "RESEARCH_COMPANY_RISKRATING") {
                            isVisible = this.ClaimsAuthorizationService.Validate("api/v1/riskratings/{companyId}", "GET", [])
                        }
                        else if (node.code === "PORTFOLIO_ANALYTICS") {
                            isAllowed = this.ClaimsAuthorizationService.Validate("api/v1/portfolios", "GET", [{ key: 'shortName', value: 'portfolioanalytics' }])
                        }

                        var nodeRoute = new SiteMapNodeRoute(routeInfo, formattedPath, isAllowed, isVisible);

                        def.resolve(nodeRoute);
                    });
                } else {
                    def.resolve(new SiteMapNodeRoute(routeInfo, formattedPath, false, false));
                }
            } else {
                def.resolve(null);
            }

            return def.promise;
        }

        private formatPath(node: SiteMapNode): string {
            var ctx = this;

            // format path according to route
            var formattedPath: string = '';

            // get route params
            var routeParams: any = ctx.RoutingService.getRouteEngineAdapter().getRouteParams();

            if (routeParams) {

                formattedPath = node.path;

                for (var param in routeParams) {
                    var paramValue = routeParams[param];
                    formattedPath = formattedPath.replace(':' + param, paramValue);
                    formattedPath = formattedPath.replace(':' + param + '?', paramValue);
                }

                // remove optional params [commented for now because of navigation menu and ui router]
                //formattedPath = formattedPath.replace(/\/:[^\/]+/g, '');
            }

            return formattedPath;
        }

        private checkRouteSecurity(node: SiteMapNode, routeSecurity: Routing.RouteSecurity): ng.IPromise<boolean> {
            var ctx = this;
            var isAllowedPromise = ctx.RoutingService.validateRouteSecurity(routeSecurity);

            if (node.code === "TOOLS") {

                isAllowedPromise.then((value) => {
                    if (!value) {
                        routeSecurity.resources[0].resource = "api/v1/datareportingtool";

                        isAllowedPromise = ctx.RoutingService.validateRouteSecurity(routeSecurity);

                        return isAllowedPromise;
                    } else {
                        return isAllowedPromise;
                    }
                });

            } 

            return isAllowedPromise;
        }
    }


    export var siteMapNodeRouteResolverServiceName = 'SiteMapNodeRouteResolverService';

    angular.module(navigationModuleName).service(siteMapNodeRouteResolverServiceName,
        ['$q', 'ClaimsAuthorizationService','RoutingService', SiteMapNodeRouteResolverService]);
}